﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using ItalcoTransfer.italco.utils;
using ItalcoTransfer;
using ItalcoTransfer.enums;

namespace ItalcoTransfer.italco.vo
{    
    public class EmployeeVO
    {
        
        #region Variables privadas
        private enums.enumTipoRegistro _eTipoRegistro;
        private string _sNumero;
        private string _sPeriodo;
        private string _sTT;
        private string _sPAC;
        private string _sActionType;

        public List<string> _sections;
        private List<FieldVO> _fields;        
        #endregion

        public EmployeeVO()
        {
            _sections = new List<string>();
            _fields = new List<FieldVO>();
            _eTipoRegistro = enums.enumTipoRegistro.Alta;            
        }

        public EmployeeVO(EmployeeVO inValue)
        {
            this.Fields = CopyFields(inValue.Fields);
            this.Numero = inValue.Numero;
            this.PAC = inValue.PAC;
            this.Periodo = inValue.Periodo;
            this.Sections = inValue.Sections;
            this.TipoRegistro = inValue.TipoRegistro;
            this.TT = inValue.TT;
            this.ActionType = inValue.ActionType;
        }


        #region Propiedades
        public enums.enumTipoRegistro TipoRegistro
        {
            get
            {
                return _eTipoRegistro;
            }
            set
            {
                _eTipoRegistro = value;
            }
        }        
        public string ActionType
        {
            get
            {
                return _sActionType;
            }
            set
            {
                _sActionType = value;
            }
        }
        public string Numero
        {
            get
            {
                return _sNumero;
            }
            set
            {
                _sNumero = value;
            }
        }
        public string Periodo
        {
            get
            {
                return _sPeriodo;
            }
            set
            {
                _sPeriodo = value;
            }
        }
        public string TT
        {
            get
            {
                return _sTT;
            }
            set
            {
                _sTT = value;
            }
        }
        public string PAC
        {
            get
            {
                return _sPAC;
            }
            set
            {
                _sPAC = value;
            }
        }
        public List<FieldVO> Fields
        {
            get
            {
                return _fields;
            }
            set
            {
                _fields = value;
            }
        }
        public List<string> Sections
        {
            get
            {
                return _sections;
            }
            set
            {
                _sections = value;
            }
        }
        #endregion

        #region Metodos
        private List<FieldVO> CopyFields( List<FieldVO> inValue)
        {
            List<FieldVO> listValues = new List<FieldVO>();
            foreach (FieldVO fvo in inValue)
            {
                listValues.Add(new FieldVO(fvo));
            }
            return listValues;
        }

        public bool AddField(FieldVO field)
        {
            //TODO: habrá lógica para uno de los campos de la seccion rubricas
            //seguramente se tendrá que modificar aqui.
            AddSection(field.NombreSeccion);
            
            ///Logica para familiares.
            ///Para cada valor de famille, se ordena por FAM_H1DDEB y FAM_FA1CODE
            ///el xml a generar es <campo id="nombrecampo" sec="valor de FAM_FA1CODE" fecha="valor de FAM_H1DDEB"> Valor del campo </campo>
            ///Por tanto, según esta lógica, permitiremos añadir campos sin restricción y sin modificar el SEC.
            ///Si el campo está definido como múltiple, lo añadiremos aunque haya campos iguales.
            ///

            //int iCoincidencias = (from x in this.Fields
            //                      where x.NombreSeccion == field.NombreSeccion
            //                          && x.ID == field.ID
            //                          && x.NumeroCampo == field.NumeroCampo
            //                      select x).Count();
            
            //if (iCoincidencias == 0 || field.RegistroMultiple)
            //{
            //    Fields.Add(field);
            //}
            return true;
            
        }
        private bool AddSection(string section)
        {
            if (!_sections.Contains(section) && section!= null && section != "")
            {
                _sections.Add(section);
                return true;
            }
            else
                return false;
        }

        public string GenerateXML(ref List<ErrorInfo> Errores)
        {
            try
            {
                //CASUISTICAS

                string sEmp = Resources.TextosTraduccionXML.TraduccionEmpleado_Body_6Params;

                string sCadenaFields = "" ;
                string sCabeceraSeccion = "";

                foreach (string sSection in Sections)
                {
                    sCabeceraSeccion = string.Format(Resources.TextosTraduccionXML.TraduccionSeccion_Cabecera_1Param, sSection) + "\n";
                    var oFieldsSection = (from ofields in Fields 
                                          where ofields.NombreSeccion == sSection    
                                            select ofields )
                                        .OrderBy(f => 
                                        {
                                            string s1 = "00";
                                            string s2 = "19000101";
                                            foreach (FieldPropertyVO p in f.FieldProperties)
                                            {
                                                if (p.NombrePropiedad == "SEC" && p.Valor != null && p.Valor != "")
                                                    s1 = p.Valor;
                                                else if (p.NombrePropiedad == "FECHA" && p.Valor != null && p.Valor != "")
                                                    s2 = DateTime.Parse(p.Valor).ToString("yyyyMMdd");
                                            }
                                            return string.Format("{1}{0}", s1, s2);
                                        }, new CaseInsensitiveComparer())
                                        ;

                    string sCamposSeccion = "";
                    foreach (FieldVO oField in oFieldsSection)
                    {
                        string sCampo = "";
                        sCampo = oField.GenerateXML(TipoRegistro, ref Errores);
                        if (sCampo!= "")
                            sCamposSeccion += sCampo + "\n";
                        //sCadenaFields += oField.GenerateXML(TipoRegistro, ref Errores) + "\n";
                    }
                    if (sCamposSeccion != "")
                    {
                        sCadenaFields += sCabeceraSeccion + sCamposSeccion + Resources.TextosTraduccionXML.TraduccionSeccion_Pie + "\n";
                    }
                    
                }
                string sTipo="A";
                switch (this.TipoRegistro)
                {
                    case enumTipoRegistro.Alta:
                        sTipo = "A";
                        break;
                    case enumTipoRegistro.Baja:
                        sTipo = "B";
                        break;
                    case enumTipoRegistro.Modificacion:
                        sTipo = "M";
                        break;
                }
                string sPeriodo = "";
                if (Periodo != null && Periodo != "")
                    sPeriodo = Periodo;
                sEmp = string.Format(sEmp, sTipo, Numero, sPeriodo, TT, PAC, sCadenaFields);
                return sEmp;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }

        }
        public void ChangeFieldsValues(EmployeeVO emp)
        {
            try
            {
                //Segun el event_type modificamos el valor de unos campos determinados
                switch (ActionType)
                {           
                    case "VNAME":
                        break;
                     
                    case "VNID":
                        break;

                        //c
                    case "VCSTS":
                        break;
                    
                    //cambio de Domicilio
                    //campos: ADG_ADPADO(28), ADG_ADVODO(29), ADG_ADLDDO(30), ADG_ADLODO(33), ADG_MUNICIPIO(34), ADG_SPADC1(37), ADG_ADNVDO(38), ADG_ADCPDO(42)                        
                    case "VHADDR":                        
                        emp.Fields.Where(x => x.ID == "ADG_ADPADO").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "ADG_ADPADO").SingleOrDefault().Valor;
                        emp.Fields.Where(x => x.ID == "ADG_ADVODO").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "ADG_ADVODO").SingleOrDefault().Valor;
                        emp.Fields.Where(x => x.ID == "ADG_ADLODO").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "ADG_ADLODO").SingleOrDefault().Valor;
                        emp.Fields.Where(x => x.ID == "ADG_ADLODO").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "ADG_ADLODO").SingleOrDefault().Valor;
                        emp.Fields.Where(x => x.ID == "ADG_MUNICIPIO").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "ADG_MUNICIPIO").SingleOrDefault().Valor;
                        emp.Fields.Where(x => x.ID == "ADG_SPADC1").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "ADG_SPADC1").SingleOrDefault().Valor;
                        emp.Fields.Where(x => x.ID == "ADG_ADNVDO").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "ADG_ADNVDO").SingleOrDefault().Valor;
                        emp.Fields.Where(x => x.ID == "ADG_ADCPDO").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "ADG_ADCPDO").SingleOrDefault().Valor;

                        break;

                    case "VPHONE":
                        break;

                    case "VLOC":                       
                        emp.Fields.Where(x => x.ID == "SAD_SACH2").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "SAD_SACH2").SingleOrDefault().Valor;                        

                        break;
                        
                        //Cambio Estado Civil
                    case "VSUPV":
                        break;
                    
                        //cambio de Centro de Costo
                        //campos : SAD_SACH3 (Cost Center)
                    case "VCDC":
                        emp.Fields.Where(x => x.ID == "SAD_SACH3").SingleOrDefault().Valor = this.Fields.Where(x => x.ID == "SAD_SACH3").SingleOrDefault().Valor;
                        break;
                        
                    case "VCNT":
                        break;
                    case "VEXEND":
                        break;

                    case "VRML":
                        break;

                    case "VCTG":
                        break;

                    case "VMBOT":
                        break;
                }
                //if (ActionType == "VCDC")
                //{
                //    //accedo a los campos que me interesa modificar de Empleado
                //     //  foreach (FieldVO oField in retValue.Fields.Where(x => x.NombreSeccion == null || x.NombreSeccion == ""))
                //    foreach (FieldVO field in emp.Fields.Where(x => x.ID == "SAD_SACH3"))
                //        foreach(FieldVO newField in this.Fields.Where(x => x.ID == "SAD_SACH3"))
                //            field.Valor = newField.Valor;                   
                //}

            }
            catch (Exception ex)
            {
            }
        }

        public EmployeeVO FillFromTXT(string[] campos, string LastID, string LastPeriodo, ref HyperFileVO hyperfile)
        {
            bool AddingExtraInfo = false;
            EmployeeVO retValue = new EmployeeVO(this);
            EmployeeVO prevValue = new EmployeeVO();

            //Fill Propiedades Empleado y proceso
            enumTipoRegistro eTipoRegistro= enumTipoRegistro.Alta;
            string sNumero="";
            string sPeriodo="";
            try
            {
                #region Rellenamos valores Empleado
                foreach (FieldVO oField in retValue.Fields.Where(x => x.NombreSeccion == null || x.NombreSeccion == ""))
                {
                    oField.FillFromTXT(campos, ref hyperfile.Errores);                    
                    foreach (FieldPropertyVO propert in oField.FieldProperties)
                    {
                        MinimasterVO oMinimaster = ItalcoTransfer.Map.Structure.Minimasters.Where(x => x.Name == "ActionTypes").First();
                        switch (propert.NombrePropiedad)
                        {
                            case "ACTION_TYPE":
                                ActionType = propert.Valor.Trim();
                                if (oMinimaster == null)
                                { eTipoRegistro = enumTipoRegistro.Alta; }
                                else
                                {
                                    if (propert.Valor != null && oMinimaster.Valores.ContainsKey(propert.Valor.Trim()))
                                    {
                                        string sValorDiccionario =
                                                oMinimaster.Valores[propert.Valor.Trim()].ToString();
                                        if (sValorDiccionario == "A")
                                            eTipoRegistro = enumTipoRegistro.Alta;
                                        else if (sValorDiccionario == "B")
                                            eTipoRegistro = enumTipoRegistro.Baja;
                                        else
                                            eTipoRegistro = enumTipoRegistro.Modificacion;
                                    }
                                    else
                                        eTipoRegistro = enumTipoRegistro.Modificacion;
                                }
                                break;
                            case "NUMERO":
                                sNumero = propert.Valor.Trim();
                                break;
                            case "PERIODO":
                                sPeriodo = propert.Valor == null ? "" : propert.Valor.Trim();                               
                                break;
                        }
                    }
                }
                #endregion


                //if (sNumero.Trim() == ""
                //        && (from emp in hyperfile.Employees
                //            where emp.Numero == LastID && emp.Periodo == LastPeriodo
                //            select emp).Count() > 0
                //    )
                //{
                //    prevValue = (from emp in hyperfile.Employees
                //                 where emp.Numero == LastID && emp.Periodo == LastPeriodo
                //                 select emp).First();
                //    AddingExtraInfo = true;
                //}
                //if (!AddingExtraInfo)
                //{
                    if (sNumero.Trim() == ""
                            && (from emp in hyperfile.Employees
                                where emp.Numero == LastID
                                select emp).Count() > 0
                        )
                    {
                        prevValue = (from emp in hyperfile.Employees
                                     where emp.Numero == LastID
                                     select emp).First();
                        AddingExtraInfo = true;
                    }
                    if (!AddingExtraInfo)
                    {
                        retValue = new EmployeeVO(this);
                        //Valores fijos.... podría cambiar, depende de Marisa.
                        retValue.PAC = "991071";
                        retValue.TT = "MN";
                        retValue.Numero = sNumero;

                        retValue.Periodo = sPeriodo;
                        retValue.TipoRegistro = eTipoRegistro;
                    }
                //}
                foreach (FieldVO oField in retValue.Fields.Where(x => x.NombreSeccion != null && x.NombreSeccion != ""))
                {
                    FieldVO oCampoRetorno = oField.FillFromTXT(campos, ref hyperfile.Errores);
                    this.AddSection(oCampoRetorno.NombreSeccion);
                    if (AddingExtraInfo & oCampoRetorno.Valor != "")
                    {
                        prevValue.AddField(oCampoRetorno);
                    }                    

                }
            }
            catch (Exception ex)
            {
                hyperfile.Errores.Add(new ErrorInfo(string.Format(Resources.TextosError.Error_General_2_Params,
                    ex.Message, ex.Source), this._sNumero));
            }
            //if (AddingExtraInfo)
            //    retValue = null;
            return retValue;
        }
        #endregion
    }
}
